package com.violet.service.manager.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.violet.domain.dto.manager.MRiderDto;
import com.violet.domain.po.Rider;
import com.violet.domain.result.ResultPage;
import com.violet.domain.search.MyPage;
import com.violet.domain.search.manager.MRiderSearch;
import com.violet.domain.vo.manager.MRiderVo;
import com.violet.mapper.RiderMapper;
import com.violet.service.manager.MRiderService;
import com.violet.utils.SearchUtils;
import com.violet.utils.TransitionUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Stream;

@Service
@RequiredArgsConstructor
public class MRiderServiceImpl extends ServiceImpl<RiderMapper, Rider>
        implements MRiderService {

    private final TransitionUtils<MRiderDto, Rider, MRiderVo> transition;

    @Override
    public ResultPage<List<MRiderVo>> search(MRiderSearch search, MyPage myPage) {
        Page<Rider> page = new Page<>(myPage.getCurrentPage(), myPage.getPageSize());
        baseMapper.selectPage(page, SearchUtils.getSearchWrapper(search));
        Stream<MRiderVo> stream = page.getRecords().stream().map(item -> transition.transition(item, MRiderVo.class));
        return ResultPage.success(stream.toList(), "分页搜索", page);
    }

    @Override
    public List<MRiderVo> getOnJobAll() {
        return baseMapper.selectList(new LambdaQueryWrapper<Rider>().eq(Rider::getStatus, true))
            .stream()
            .map(item -> transition.transition(item, MRiderVo.class))
            .toList();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MRiderVo create(MRiderDto dto) {
        Rider rider = transition.transition(dto, Rider.class);
        try {
            baseMapper.insert(rider);
        }
        catch (DuplicateKeyException e) {throw new RuntimeException("手机号重复");}
        return transition.transition(rider, MRiderVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE)
    public Boolean deleteById(String id) {
        Rider rider = baseMapper.getByIdWithPessimisticLock(id);
        if (rider == null) throw new RuntimeException("骑手不存在");
        return baseMapper.deleteById(rider) == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ)
    public MRiderVo updateById(String id, MRiderDto dto) {
        Rider rider = baseMapper.getByIdWithPessimisticLock(id);
        if (rider == null) throw new RuntimeException("骑手不存在");
        // 复制数据
        transition.copy(dto, rider);
        // 是否离职
        if (!rider.getStatus()) rider.setLeaveTime(LocalDateTime.now());
        else rider.setLeaveTime(null);
        // 入库
        baseMapper.updateById(rider);
        // 返回
        return transition.transition(rider, MRiderVo.class);
    }

}
